使用Java语言 利用OpenCV,对两种图片相似度对比 您所在的位置:网站首页 java 图片比较 使用Java语言 利用OpenCV,对两种图片相似度对比

使用Java语言 利用OpenCV,对两种图片相似度对比

2024-07-13 05:59| 来源: 网络整理| 查看: 265

下边是代码部分

import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc;

import java.io.*; import java.net.URL; import java.util.ArrayList; import java.util.List;

import org.opencv.features2d.*; import org.opencv.core.MatOfDMatch; import org.opencv.core.DMatch;

public class OpenCVImageSimilarity {

public static void main(String[] args) throws IOException {

// 加载OpenCV库

// 读取两张图像。准备比对的图片 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 加载OpenCV库NATIVE_LIBRARY_NAME String imageUrl1 = "https://img/0b653e8b-d306-4e15-8e64-4d2212a7434b.jpg"; String imageUrl2 = "https://img/98845b33-0237-45a1-a91d-714d6aba0c3c.jpg";

Mat image1 = readImageFromUrl(imageUrl1); // 调用方法读取网络图片 Mat image2 = readImageFromUrl(imageUrl2); double rdb=rdbSimilar(image1,image2); double hash= meanHash(image1, image2); double hist= histogram(image1, image2); double result=(rdb+hash+hist)/ 3; System.out.println("RDB相似度:" +rdb ); System.out.println("均值哈希算法计算相似度:"+hash); System.out.println("图片相似度(直方图): " + hist);

/* if (image1 != null) { // 图片读取成功,可以进行后续处理或保存 // 这里只是示例将图片保存到本地 String outputPath = "output.jpg"; Imgcodecs.imwrite(outputPath, image1); System.out.println("图片保存成功: " + outputPath); } else { System.out.println("图片读取失败"); }*/ // 将图片处理成一样大

// 计算归一化交叉相关(NCC) // double ncc = calculateNCC(image1, image2); // System.out.println("归一化交叉相关(NCC): " + ncc); } private static Mat readImageFromUrl(String imageUrl) { Mat image = null; try { // 使用URL类打开网络图片的输入流 URL url = new URL(imageUrl); BufferedInputStream inputStream = new BufferedInputStream(url.openStream());

// 将输入流解码为OpenCV的Mat对象 byte[] imageData = inputStream.readAllBytes(); image = Imgcodecs.imdecode(new MatOfByte(imageData), Imgcodecs.IMREAD_COLOR); } catch (IOException e) { e.printStackTrace(); } return image; } static double histogram(Mat image1, Mat image2){ Imgproc.resize(image1, image1, image2.size()); Imgproc.resize(image2, image2, image1.size());

// 计算均方差(MSE) double mse = calculateMSE(image1, image2); // System.out.println("均方差(MSE): " + mse);

// 计算结构相似性指数(SSIM) double ssim = calculateSSIM(image1, image2); //System.out.println("结构相似性指数(SSIM): " + ssim);

// 计算峰值信噪比(PSNR) double psnr = calculatePSNR(image1, image2); // System.out.println("峰值信噪比(PSNR): " + psnr);

// 计算直方图 final double similarity = calculateHistogram(image1, image2); // System.out.println("图片相似度(直方图): " + similarity); return similarity;

}

// 计算均方差(MSE) private static double calculateHistogram(Mat image1, Mat image2) { // 计算直方图 Mat hist1 = calculateHistogram(image1); Mat hist2 = calculateHistogram(image2);

// 计算相似度 final double similarity = Imgproc.compareHist(hist1, hist2, Imgproc.CV_COMP_CORREL); return similarity; }

// 计算均方差(MSE) private static double calculateMSE(Mat image1, Mat image2) { Mat diff = new Mat(); Core.absdiff(image1, image2, diff); Mat squaredDiff = new Mat(); Core.multiply(diff, diff, squaredDiff); Scalar mseScalar = Core.mean(squaredDiff); return mseScalar.val[0]; }

// 计算结构相似性指数(SSIM) private static double calculateSSIM(Mat image1, Mat image2) { Mat image1Gray = new Mat(); Mat image2Gray = new Mat(); Imgproc.cvtColor(image1, image1Gray, Imgproc.COLOR_BGR2GRAY); Imgproc.cvtColor(image2, image2Gray, Imgproc.COLOR_BGR2GRAY); MatOfFloat ssimMat = new MatOfFloat(); Imgproc.matchTemplate(image1Gray, image2Gray, ssimMat, Imgproc.CV_COMP_CORREL); Scalar ssimScalar = Core.mean(ssimMat); return ssimScalar.val[0]; }

// 计算峰值信噪比(PSNR) private static double calculatePSNR(Mat image1, Mat image2) { Mat diff = new Mat(); Core.absdiff(image1, image2, diff); Mat squaredDiff = new Mat(); Core.multiply(diff, diff, squaredDiff); Scalar mseScalar = Core.mean(squaredDiff); double mse = mseScalar.val[0]; double psnr = 10.0 * Math.log10(255.0 * 255.0 / mse); return psnr; }

// 计算归一化交叉相关(NCC) // private static double calculateNCC(Mat image1, Mat image2) { // Mat image1Gray = new Mat(); // Mat image2Gray = new Mat(); // Imgproc.cvtColor(image1, image1Gray, Imgproc.COLOR_BGR2GRAY); // Imgproc.cvtColor(image2, image2Gray, Imgproc.COLOR_BGR2GRAY); // MatOfInt histSize = new MatOfInt(256); // MatOfFloat ranges = new MatOfFloat(0, 256); // Mat hist1 = new Mat(); // Mat hist2 = new Mat(); // // Core.normalize(hist1, hist1, 0, 1, Core.NORM_MINMAX); // Core.normalize(hist2, hist2, 0, 1, Core.NORM_MINMAX); // double ncc = Core.compareHist(hist1, hist2, Imgproc.CV_COMP_CORREL); // return ncc; // }

private static Mat calculateHistogram(Mat image) { Mat hist = new Mat();

// 设置直方图参数 MatOfInt histSize = new MatOfInt(256); MatOfFloat ranges = new MatOfFloat(0, 256); MatOfInt channels = new MatOfInt(0); List images = new ArrayList(); images.add(image);

// 计算直方图 Imgproc.calcHist(images, channels, new Mat(), hist, histSize, ranges);

return hist; } static double rdbSimilar(Mat img1, Mat img2){ // 加载OpenCV库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

// 读取两张图片 /* Mat img1 = Imgcodecs.imread("path/to/your/image1.jpg"); Mat img2 = Imgcodecs.imread("path/to/your/image2.jpg");*/

// 创建ORB特征检测器和描述子提取器 ORB orb = ORB.create();

// 检测图像中的特征点并计算描述子 MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); Mat descriptors1 = new Mat(); Mat descriptors2 = new Mat(); orb.detectAndCompute(img1, new Mat(), keypoints1, descriptors1); orb.detectAndCompute(img2, new Mat(), keypoints2, descriptors2);

// 创建描述子匹配器 DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

// 匹配描述子 MatOfDMatch matches = new MatOfDMatch(); matcher.match(descriptors1, descriptors2, matches);

// 计算匹配结果的相似度 double maxDist = 0; double minDist = 100; DMatch[] matchArray = matches.toArray(); for (int i = 0; i < matchArray.length; i++) { double dist = matchArray[i].distance; if (dist < minDist) { minDist = dist; } if (dist > maxDist) { maxDist = dist; } }

// 输出相似度 double v = 1 - minDist / maxDist; //System.out.println("最小距离:" + minDist); // System.out.println("最大距离:" + maxDist); // System.out.println("RDB相似度:" +v ); return v; }

static double meanHash(Mat img1, Mat img2){ Mat grayImg1 = new Mat(); Mat grayImg2 = new Mat(); Imgproc.cvtColor(img1, grayImg1, Imgproc.COLOR_BGR2GRAY); Imgproc.cvtColor(img2, grayImg2, Imgproc.COLOR_BGR2GRAY); // 缩放图像至固定大小 Size targetSize = new Size(8, 8); Mat resizedImg1 = new Mat(); Mat resizedImg2 = new Mat(); Imgproc.resize(grayImg1, resizedImg1, targetSize); Imgproc.resize(grayImg2, resizedImg2, targetSize);

// 计算均值哈希值 String hash1 = calculateMeanHash(resizedImg1); String hash2 = calculateMeanHash(resizedImg2);

// 计算汉明距离并计算相似度 int hammingDistance = calculateHammingDistance(hash1, hash2); double similarity = 1 - (double) hammingDistance / (targetSize.width * targetSize.height);

return similarity; }

private static String calculateMeanHash(Mat image) { double sum = 0; int totalPixels = image.rows() * image.cols();

for (int i = 0; i < image.rows(); i++) { for (int j = 0; j < image.cols(); j++) { double pixelValue = image.get(i, j)[0]; sum += pixelValue; } }

double mean = sum / totalPixels; StringBuilder hash = new StringBuilder();

for (int i = 0; i < image.rows(); i++) { for (int j = 0; j < image.cols(); j++) { double pixelValue = image.get(i, j)[0]; if (pixelValue >= mean) { hash.append("1"); } else { hash.append("0"); } } }

return hash.toString(); }

public static int hammingDistance2(int hash1, int hash2){

int num = hash1 ^ hash2;

int count = 0;

for(; num > 0; count++)

{

num &= (num - 1);

}

return count;

} private static int calculateHammingDistance(String hash1, String hash2) { int distance = 0;

for (int i = 0; i < hash1.length(); i++) { if (hash1.charAt(i) != hash2.charAt(i)) { distance++; } }

return distance; }

}

下载opencv官方地址:https://opencv.org/releases/ 安装opencv参考地址:https://blog.csdn.net/star1210644725/article/details/131004810?csdn_share_tail={"type"%3A"blog"%2C"rType"%3A"article"%2C"rId"%3A"131004810"%2C"source"%3A"star1210644725"}

如果是linux环境:需要把System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 注释掉。然后在类中加入静态方法 static { OpenCV.LoadShared(); }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有